﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Obtics.Values.Transformations;

namespace Obtics.Values
{
    /// <summary>
    /// This class contains public methods needed by the system. These methods are not intended to be used by your code.
    /// </summary>
#if !FULL_REFLECTION
    public 
#endif
    static class RewriterHelper
    {
        //cache the results of the pipeline factories.
        //The result of a successful rewrite and compilation is not a value transformation pipeline but
        //rather a delegate (object) that knows how to create a value transformation pipeline from certain
        //input parameters (factory) .
        //
        //It is not uncommon that this process of creating a pipeline (or finding a previously created one)
        //is an expensive process.
        //
        //Here we create objects (PipelineResultTransformation) whose identities depent solely on the input parameters
        //of the generating method. We do not first have to construct the entiry transformation tree to see if it already exists
        //If the input parameters are the same then the transformation tree will be the same.
        //
        //In this section we cap the created factory of with a caching object (Carrousel). 

        //Generator objects serve as factories of the transformation pipeline.
        //PipelineResultTransformation gets a factory and its input parameters. Only when a result is requested
        //will the transformation tree be instantiated
        internal class Generator<TType> : IValueTransformationPipelineFactory<Func<IValueProvider<TType>>, TType>
        {
            public IValueProvider<TType> Create(Func<IValueProvider<TType>> key)
            { return key(); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher0<TType>(Func<IValueProvider<TType>> generator)
        { return PipelineResultTransformation<Func<IValueProvider<TType>>, TType, Generator<TType>>.Create(generator).Concrete(); }

        internal class Generator<TArg1, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, IValueProvider<TType>>, TArg1>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, IValueProvider<TType>>, TArg1> key)
            { return key.First(key.Second); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher1<TArg1, TType>(Func<TArg1, IValueProvider<TType>> generator, TArg1 arg1)
        { return PipelineResultTransformation<Tuple<Func<TArg1, IValueProvider<TType>>, TArg1>, TType, Generator<TArg1, TType>>.Create(Tuple.Create(generator, arg1)).Concrete(); }

        internal class Generator<TArg1, TArg2, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, IValueProvider<TType>>, TArg1, TArg2>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, IValueProvider<TType>>, TArg1, TArg2> key)
            { return key.First(key.Second, key.Third); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher2<TArg1, TArg2, TType>(Func<TArg1, TArg2, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, IValueProvider<TType>>, TArg1, TArg2>, TType, Generator<TArg1, TArg2, TType>>.Create(Tuple.Create(generator, arg1, arg2)).Concrete(); }

        internal class Generator<TArg1, TArg2, TArg3, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, IValueProvider<TType>>, TArg1, TArg2, TArg3>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, IValueProvider<TType>>, TArg1, TArg2, TArg3> key)
            { return key.First(key.Second, key.Third, key.Fourth); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher3<TArg1, TArg2, TArg3, TType>(Func<TArg1, TArg2, TArg3, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, IValueProvider<TType>>, TArg1, TArg2, TArg3>, TType, Generator<TArg1, TArg2, TArg3, TType>>.Create(Tuple.Create(generator, arg1, arg2, arg3)).Concrete(); }

        internal class Generator<TArg1, TArg2, TArg3, TArg4, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, IValueProvider<TType>>, TArg1, TArg2, TArg3, TArg4>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, IValueProvider<TType>>, TArg1, TArg2, TArg3, TArg4> key)
            { return key.First(key.Second, key.Third, key.Fourth, key.Fifth); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher4<TArg1, TArg2, TArg3, TArg4, TType>(Func<TArg1, TArg2, TArg3, TArg4, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, IValueProvider<TType>>, TArg1, TArg2, TArg3, TArg4>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TType>>.Create(Tuple.Create(generator, arg1, arg2, arg3, arg4)).Concrete(); }


        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5> key)
            {
                var s1 = key.Second;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, key.Third); }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher5<TArg1, TArg2, TArg3, TArg4, TArg5, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), arg5)).Concrete(); }


        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6> key)
            {
                var s1 = key.Second;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, key.Third, key.Fourth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher6<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), arg5, arg6)).Concrete(); }



        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6, TArg7>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6, TArg7> key)
            {
                var s1 = key.Second;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, key.Third, key.Fourth, key.Fifth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher7<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, TArg5, TArg6, TArg7>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), arg5, arg6, arg7)).Concrete(); }



        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher8<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8))).Concrete(); }



        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, key.Fourth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher9<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), arg9)).Concrete(); }




        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9, TArg10>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9, TArg10> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, key.Fourth, key.Fifth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher10<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, TArg9, TArg10>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), arg9, arg10)).Concrete(); }




        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher11<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11))).Concrete(); }





        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third, s3.Fourth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TArg12"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <param name="arg12"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher12<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11, arg12))).Concrete(); }




        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, TArg13>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, TArg13> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third, s3.Fourth, key.Fifth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TArg12"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <typeparam name="TArg13"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <param name="arg12"></param>
        /// <param name="arg13"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher13<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, TArg13>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11, arg12), arg13)).Concrete(); }





        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                var s4 = key.Fifth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third, s3.Fourth, s4.First, s4.Second);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TArg12"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <typeparam name="TArg13"></typeparam>
        /// <typeparam name="TArg14"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <param name="arg12"></param>
        /// <param name="arg13"></param>
        /// <param name="arg14"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher14<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11, arg12), Tuple.Create(arg13, arg14))).Concrete(); }





        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                var s4 = key.Fifth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third, s3.Fourth, s4.First, s4.Second, s4.Third);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TArg12"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <typeparam name="TArg13"></typeparam>
        /// <typeparam name="TArg14"></typeparam>
        /// <typeparam name="TArg15"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <param name="arg12"></param>
        /// <param name="arg13"></param>
        /// <param name="arg14"></param>
        /// <param name="arg15"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher15<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11, arg12), Tuple.Create(arg13, arg14, arg15))).Concrete(); }





        internal class Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TType> : IValueTransformationPipelineFactory<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15, TArg16>>, TType>
        {
            public IValueProvider<TType> Create(Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15, TArg16>> key)
            {
                var s1 = key.Second;
                var s2 = key.Third;
                var s3 = key.Fourth;
                var s4 = key.Fifth;
                return key.First(s1.First, s1.Second, s1.Third, s1.Fourth, s2.First, s2.Second, s2.Third, s2.Fourth, s3.First, s3.Second, s3.Third, s3.Fourth, s4.First, s4.Second, s4.Third, s4.Fourth);
            }
        }

        /// <summary>
        /// Provides caching mechanism for a pipeline generated by a given function.
        /// </summary>
        /// <typeparam name="TArg1"></typeparam>
        /// <typeparam name="TArg2"></typeparam>
        /// <typeparam name="TArg3"></typeparam>
        /// <typeparam name="TArg4"></typeparam>
        /// <typeparam name="TArg5"></typeparam>
        /// <typeparam name="TArg6"></typeparam>
        /// <typeparam name="TArg7"></typeparam>
        /// <typeparam name="TArg8"></typeparam>
        /// <typeparam name="TArg9"></typeparam>
        /// <typeparam name="TArg10"></typeparam>
        /// <typeparam name="TArg11"></typeparam>
        /// <typeparam name="TArg12"></typeparam>
        /// <typeparam name="TType"></typeparam>
        /// <typeparam name="TArg13"></typeparam>
        /// <typeparam name="TArg14"></typeparam>
        /// <typeparam name="TArg15"></typeparam>
        /// <typeparam name="TArg16"></typeparam>
        /// <param name="generator"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <param name="arg3"></param>
        /// <param name="arg4"></param>
        /// <param name="arg5"></param>
        /// <param name="arg6"></param>
        /// <param name="arg7"></param>
        /// <param name="arg8"></param>
        /// <param name="arg9"></param>
        /// <param name="arg10"></param>
        /// <param name="arg11"></param>
        /// <param name="arg12"></param>
        /// <param name="arg13"></param>
        /// <param name="arg14"></param>
        /// <param name="arg15"></param>
        /// <param name="arg16"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static IValueProvider<TType> Cacher16<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TType>(Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IValueProvider<TType>> generator, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11, TArg12 arg12, TArg13 arg13, TArg14 arg14, TArg15 arg15, TArg16 arg16)
        { return PipelineResultTransformation<Tuple<Func<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, IValueProvider<TType>>, Tuple<TArg1, TArg2, TArg3, TArg4>, Tuple<TArg5, TArg6, TArg7, TArg8>, Tuple<TArg9, TArg10, TArg11, TArg12>, Tuple<TArg13, TArg14, TArg15, TArg16>>, TType, Generator<TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TArg16, TType>>.Create(Tuple.Create(generator, Tuple.Create(arg1, arg2, arg3, arg4), Tuple.Create(arg5, arg6, arg7, arg8), Tuple.Create(arg9, arg10, arg11, arg12), Tuple.Create(arg13, arg14, arg15, arg16))).Concrete(); }




        //MethodInfos of various VPFinder.SelectExt methods
        /// <summary>
        /// Calls a typed function with a sequence of parameters taken from an untyped array.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="prms"></param>
        /// <param name="from"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static TResult SelectExt1<T1, TResult>(object[] prms, int from, Func<T1, TResult> func)
        { return func((T1)prms[from]); }

        /// <summary>
        /// Calls a typed function with a sequence of parameters taken from an untyped array.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="prms"></param>
        /// <param name="from"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static TResult SelectExt2<T1, T2, TResult>(object[] prms, int from, Func<T1, T2, TResult> func)
        { return func((T1)prms[from], (T2)prms[from + 1]); }

        /// <summary>
        /// Calls a typed function with a sequence of parameters taken from an untyped array.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="prms"></param>
        /// <param name="from"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static TResult SelectExt3<T1, T2, T3, TResult>(object[] prms, int from, Func<T1, T2, T3, TResult> func)
        { return func((T1)prms[from], (T2)prms[from + 1], (T3)prms[from + 2]); }

        /// <summary>
        /// Calls a typed function with a sequence of parameters taken from an untyped array.
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <typeparam name="T3"></typeparam>
        /// <typeparam name="T4"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="prms"></param>
        /// <param name="from"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static TResult SelectExt4<T1, T2, T3, T4, TResult>(object[] prms, int from, Func<T1, T2, T3, T4, TResult> func)
        { return func((T1)prms[from], (T2)prms[from + 1], (T3)prms[from + 2], (T4)prms[from + 3]); }

        //SafeCall
        /// <summary>
        /// Executes a function and returns its result only of its requiered parameter is not null. Will return a default value if the parameter is null.
        /// </summary>
        /// <typeparam name="TObject"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="obj"></param>
        /// <param name="f"></param>
        /// <returns></returns>
        /// <remarks>This method is for internal use only and not intended to be used from your code.</remarks>
        public static TResult SafeCall<TObject, TResult>(TObject obj, Func<TObject, TResult> f)
                    where TObject : class
        { return obj == null ? default(TResult) : f(obj); }
    }
}
